package com.tianyadu.mmall.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.hibernate.annotations.GenericGenerator;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.social.security.SocialUserDetails;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.*;

/**
 * 用户信息
 *
 * @author xueyj
 * @date 2019-06-06 16:54
 */
@Data
@Entity
public class SysUser implements SocialUserDetails, Serializable {

    private static final long serialVersionUID = 1585929848813585629L;
    /**
     * 用户id
     */
    @Id
    @GenericGenerator(name = "uuid", strategy = "uuid")
    @GeneratedValue(generator = "uuid")
    private String id;
    /**
     * 用户名
     */

    // @MyConstraint(message = "这是一个测试")
    private String username;

    /**
     * 密码
     */
    @NotBlank
    private String password;

    /**
     * 用户openId
     */
    private String openid;

    /**
     * 用户角色
     */
    @NotNull
    private Integer role;

    /**
     * 用户账号是否有效，true，有效；   false，无效
     */
    private boolean isEnabled = Boolean.TRUE;

    /**
     * 用户信息是否过期，true，未过期； false，已过期
     */
    private boolean accountNonExpired = Boolean.TRUE;

    /**
     * 用户账号是否锁定，true，未锁定； false，已锁定
     */
    private boolean accountNonLocked = Boolean.TRUE;

    /**
     * 用户密码是否过期，true，未过期； false，已过期
     */
    private boolean credentialsNonExpired = Boolean.TRUE;

    /**
     * 创建时间
     */
    @Temporal(TemporalType.TIMESTAMP)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;

    /**
     * 修改时间
     */
    @Temporal(TemporalType.TIMESTAMP)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date updateTime;

    /**
     * 用户-角色关系引用
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "sys_user_role_ref",
            joinColumns = @JoinColumn(name = "sys_user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "sys_role_id", referencedColumnName = "id"))
    private List<SysRole> roles;

    /**
     * 构建用户权限组信息
     * Returns the authorities granted to the user. Cannot return <code>null</code>.
     *
     * @return the authorities, sorted by natural key (never <code>null</code>)
     */
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Set<GrantedAuthority> authorities = new HashSet<>();
        List<SysRole> roles = this.getRoles();
        if (roles != null && roles.size() > 0) {
            for (SysRole role : roles) {
                Set<SysPermission> permissions = role.getPermissions();
                for (SysPermission permission : permissions) {
                    authorities.add(new SimpleGrantedAuthority(permission.getCode()));
                }
            }
        }
        return authorities;
    }

    /**
     * 用户信息是否过期，true，未过期； false，已过期
     * Indicates whether the user's account has expired. An expired account cannot be
     * authenticated.
     *
     * @return <code>true</code> if the user's account is valid (ie non-expired),
     * <code>false</code> if no longer valid (ie expired)
     */
    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired;
    }

    /**
     * 用户账号是否锁定，true，未锁定； false，已锁定
     * Indicates whether the user is locked or unlocked. A locked user cannot be
     * authenticated.
     *
     * @return <code>true</code> if the user is not locked, <code>false</code> otherwise
     */
    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked;
    }

    /**
     * 用户密码是否过期，true，未过期； false，已过期
     * Indicates whether the user's credentials (password) has expired. Expired
     * credentials prevent authentication.
     *
     * @return <code>true</code> if the user's credentials are valid (ie non-expired),
     * <code>false</code> if no longer valid (ie expired)
     */
    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }

    /**
     * 用户账号是否有效，true，有效；   false，无效
     * Indicates whether the user is enabled or disabled. A disabled user cannot be
     * authenticated.
     *
     * @return <code>true</code> if the user is enabled, <code>false</code> otherwise
     */
    @Override
    public boolean isEnabled() {
        return isEnabled;
    }

    /**
     * The user's identity at the provider.
     * Might be same as {@link #getUsername()} if users are identified by username
     *
     * @return user's id used to assign connections
     */
    @Override
    public String getUserId() {
        return username;
    }
}